home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Add-ons / CAfterDark20 / CProjectile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-03  |  3.4 KB  |  130 lines  |  [TEXT/KAHL]

  1. /*
  2.  * © Copyright Jeff Francis 1990
  3.  * All rights reserved
  4.  *
  5.  * $Id$
  6.  *
  7.  * Description - CProjectile is an example CAfterDark subclass.
  8.  * CProjectile animates a projectile across the screen.  Calculations
  9.  * are made so that the projectile doesn't fly off the screen.  The
  10.  * animation isn't all that great but it makes for a reasonable example.
  11.  */
  12.  
  13. #include "CProjectile.h"
  14.  
  15. #define kMAXVELOCITY    500
  16. #define SynchVBL()  synchFlag = ¶ms->monitors->monitorList[0].synchFlag; \
  17.                     *synchFlag = false; \
  18.                     while (!*synchFlag);
  19.  
  20. /*
  21.  * Initialize seeds the random number generator, gets the value of
  22.  * gravity from the gravity slider and then generates a set of initial
  23.  * conditions.
  24.  */
  25. OSErr CProjectile::Initialize(RgnHandle blankRgn, GMParamBlockPtr params)
  26. {
  27.     GetDateTime(&randSeed);
  28.     
  29.     fG = params->controlValues[kGRAVITY_CTRL] + 0.00000001;
  30.     fBallSize = params->controlValues[kBALLSIZE_CTRL];
  31.     this->InitialConditions(params);    
  32.     
  33.     return noErr;
  34. }
  35.  
  36.  
  37. /*
  38.  * Draw performs animation by erasing the old projectile and then
  39.  * drawing a new projectile at a new position.  The new position
  40.  * may be off the screen.  If it is, a new set of initial conditions
  41.  * are generated.  If not, "time" is incremented.
  42.  */
  43. OSErr CProjectile::DrawFrame(RgnHandle blankRgn, GMParamBlockPtr params)
  44. {
  45.     register Boolean *synchFlag;
  46.     Rect aRect1, aRect2;
  47.     float oldX, oldY;
  48.     int ballSize;
  49.     
  50.     /*
  51.      * Get new ball size
  52.      */
  53.     ballSize = params->controlValues[kBALLSIZE_CTRL];
  54.     
  55.     /*
  56.      * Calculate new particle position
  57.      */
  58.     oldX = fX;
  59.     oldY = fY;
  60.     fY = fYo + fG*fT*fT/2 - fVyo*fT;
  61.     fX = fVxo*fT + fXo;
  62.         
  63.     /*
  64.      * If the projectile is off the screen then generate a new set
  65.      * of initial conditions otherwise draw the projectile at the
  66.      * new position.
  67.      */
  68.     if (fY > params->monitors->monitorList[0].bounds.bottom) {
  69.         /*
  70.          * We've fallen off the screen.
  71.          */
  72.         SetRect(&aRect1, (int)oldX-fBallSize, (int)oldY-fBallSize,
  73.                 (int)oldX+fBallSize, (int)oldY+fBallSize);
  74.         FillOval(&aRect1, params->qdGlobalsCopy->qdBlack);
  75.         
  76.         this->InitialConditions(params);
  77.     } else {
  78.         fT += params->controlValues[kSPEED_CTRL] / 100.0;
  79.         
  80.         SetRect(&aRect1, (int)oldX-fBallSize, (int)oldY-fBallSize,
  81.                 (int)oldX+fBallSize, (int)oldY+fBallSize);
  82.         SetRect(&aRect2, (int)fX-ballSize, (int)fY-ballSize,
  83.                 (int)fX+ballSize, (int)fY+ballSize);
  84.             
  85.         SynchVBL();
  86.         FillOval(&aRect1, params->qdGlobalsCopy->qdBlack);
  87.         FillOval(&aRect2, params->qdGlobalsCopy->qdWhite);
  88.     }
  89.     
  90.     /*
  91.      * Save new ball size.
  92.      */
  93.     fBallSize = ballSize;
  94.  
  95.     return noErr;
  96. }
  97.  
  98.  
  99. /*
  100.  * InitialConditions generates a set of random initial conditions
  101.  * such that the projectile will not fly beyond the top of the monitor
  102.  * nor will it go beyond the sides of the monitor during its flight.
  103.  */
  104. void CProjectile::InitialConditions(GMParamBlockPtr params)
  105. {
  106.     float maxX, maxY;
  107.     int monitorX, monitorY, randomValue;
  108.     Str255 aString;
  109.         
  110.     monitorX = params->monitors->monitorList[0].bounds.right;
  111.     monitorY = params->monitors->monitorList[0].bounds.bottom;
  112.     
  113.     fT = fX = fY = 0.0;
  114.     
  115.     do {
  116.         randomValue = Random();
  117.         randomValue = ABS(randomValue);
  118.         fXo = randomValue % monitorX;
  119.         fYo = monitorY;
  120.         
  121.         fVxo = Random() % kMAXVELOCITY /
  122.                 (params->controlValues[kRATIO_CTRL] + 1);
  123.         randomValue = Random();
  124.         randomValue = ABS(randomValue);
  125.         fVyo = randomValue % kMAXVELOCITY;
  126.  
  127.         maxX = 2*fVyo*fVxo/fG + fXo;
  128.         maxY = fVyo*fVyo/2/fG - fYo;
  129.     } while (maxY > 0 || maxX < 0 || maxX > monitorX);
  130. }